#pragma once
#include <iostream>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/inet.h>
#include <cstdio>

#define IP "0.0.0.0"
#define PORT 8888
// struct ReciveDate
// {
//     sockaddr_in recive;
//     std::string s;
// };
class Service
{
public:
    Service(const std::string &ip = IP, const uint16_t port = PORT)
        : _ip(ip), _port(port)
    {
    }
    void Init()
    {
        // 1:创建套接字；
        _socketfd = socket(AF_INET, SOCK_DGRAM, 0);
        if (_socketfd < 0)
        {
            // 创建失败；
            perror("socket");
            return;
        }
        std::cout << "sucessecc";
        // 2：绑定套接字；
        int retval = Bind();
        if (retval < 0)
        {
            std::cout << "erro" << std::endl;
            perror("bind");
            return;
        }
        std::cout << "bind secessecc" << std::endl;
    }
    void Run()
    {
        // 1:接收；

        // 2:发送；
        std::cout << "run" << std::endl;
        while (true)
        {
            struct sockaddr_in client;
            char massage[1024];
            std::string s;
            socklen_t len = sizeof(massage);

            int n = recvfrom(_socketfd, massage, sizeof(massage), 0, (struct sockaddr *)&client, &len);
            if (n < 0)
            {
                std::cout << "error" << std::endl;
            }
            // std::cout<<"recvfrom s"<<std::endl;
            massage[n] = '\0';
            s += "recive say";
            std::string tmp = massage;
            s += tmp;
            // std::cout<<s<<std::endl;
            std::cout << "client say:" << massage << std::endl;
            // std::cout<<"recvfrom";
            // const ReciveDate date =  RecvFrom();
            // SendTo(date);
            // struct sockaddr_in tmps;
            sendto(_socketfd, s.c_str(), s.size(), 0, (const struct sockaddr *)&client, len);
        }
    }

private:
    // const ReciveDate RecvFrom()
    // {
    //     sockaddr_in recive;
    //     char ch[1024];
    //     memset(&recive,0,sizeof(recive));
    //     socklen_t len = sizeof(recive);
    //     recvfrom(_socketfd,ch,sizeof(ch) - 1,0,(sockaddr*)&recive,&len);
    //     std::cout<<ch<<std::endl;
    //     std::string s =ch;
    //     std::string message = "client say@"+s;
    //     std::cout<<message<<std::endl;
    //     return {recive,s};
    // }
    // void SendTo(const ReciveDate&date)
    // {

    //     std::string s = "service say@:";
    //     s+=date.s;
    //     std::cout<<s<<std::endl;
    //     const char*ch = s.c_str();
    //     // sendto(_socketfd,)
    //     sendto(_socketfd,ch,strlen(ch),0,(const sockaddr*)&date.recive,sizeof(date.recive));
    // }

    int Bind()
    {
        struct sockaddr_in sockin;
        memset(&sockin, 0, sizeof(sockin)); // 初始化；
        sockin.sin_port = htons(_port);     // 需要将主机字节序转换成网络字节序；
        sockin.sin_family = AF_INET;
        sockin.sin_addr.s_addr = inet_addr(_ip.c_str()); // inet_addr可以将_IP转换成网络字节序；
        int retval = bind(_socketfd, ((const struct sockaddr *)&sockin), sizeof(sockin));
        return retval;
    }

private:
    int _socketfd;   // socket 文件描述符；
    std::string _ip; // IP地址；
    uint16_t _port;  // 端口号；
};